package myJs.user.soft.preprocess

import com.softwaremill.quicklens._

import myJs.cps._
import myJs.myPkg.reactHookForm._
import myJs.tool.Tool
import myJs.tool.Tool._
import myJs.user.soft.preprocess.AllCp.PreprocessT
import shared.Pojo._
import shared.pojo.WorkflowMission._

import scala.collection.SeqMap

import japgolly.scalajs.react.vdom.all._
import japgolly.scalajs.react._
import japgolly.scalajs.react.React.Fragment
import japgolly.scalajs.react.util.EffectCatsEffect._
import myJs.myPkg.Hooks._
import cats.effect._
import myJs.Implicits._
import myJs.Utils._

/** Created by yz on 3/11/2020
  */
object LevelRemoveCp extends PreprocessT with LevelRemoveRowSoftT {

  case class Props(
      curI: Int,
      datasChange: List[EachPreprocessData] => SyncIO[Unit],
      datas: List[EachPreprocessData],
      insertModule: String => SyncIO[Unit],
      removeModule: Int => SyncIO[Unit]
  ){
    @inline def render: VdomElement = {
      Component(this)
    }
  }

  val Component = ScalaFnComponent[Props] { props =>
    object FTool {

      def accordKindChange = (v: String) => {
        val newPreProcess = props.datas.modify(_.index(props.curI).accordKind).setTo(v)
        props.datasChange(newPreProcess)
      }

      def calculateMethodChange = (v: String) => {
        val newPreProcess = props.datas.modify(_.index(props.curI).calculateMethod).setTo(v)
        props.datasChange(newPreProcess)
      }

      def keepMethodChange = (v: String) => {
        val newPreProcess = props.datas.modify(_.index(props.curI).keepMethod).setTo(v)
        props.datasChange(newPreProcess)
      }

      def constantChange = (v: String) => {
        val newPreProcess = props.datas.modify(_.index(props.curI).constant).setTo(v)
        props.datasChange(newPreProcess)
      }

      def topNChange = (v: String) => {
        val newPreProcess = props.datas.modify(_.index(props.curI).topN).setTo(v)
        props.datasChange(newPreProcess)
      }

      def topPercentChange = (v: String) => {
        val newPreProcess = props.datas.modify(_.index(props.curI).topPercent).setTo(v)
        props.datasChange(newPreProcess)
      }

      def removeModuleF =  {
        props.removeModule(props.curI)
      }

      def insertModule = (moduleName: String) => {
        props.insertModule(moduleName)
      }

    }

    useEffect(
      SyncIO{
        Tool.popover
      }.void,
      List()
    )

    val accordKindMap =
      SeqMap("qc" -> messages("qCSamples"), "noQc" -> messages("nonQCSamples"), "all" -> messages("allSamples"))
    val calculateMethodMap = SeqMap("median" -> messages("median"), "mean" -> messages("mean"))
    val keepMethodMap = SeqMap(
      "more" -> messages("greaterThanConstant"),
      "top" -> messages("takingTopN"),
      "topPercent" -> messages("takingTopProportion")
    )
    val data = props.datas(props.curI)
    val accordKind = data.accordKind
    val calculateMethod = data.calculateMethod
    val keepMethod = data.keepMethod
    val constant = data.constant
    val topN = data.topN
    val topPercent = data.topPercent
    val namePrefix = s"datas.${props.curI}"

    fieldset(
      paddingRight := "5px", border := "1px solid silver", margin := "0 2px", borderRadius := "4px",
      className := "northbtn myEachSoft",
      MyToolCp.Props(removeModule = FTool.removeModuleF, insertModule = FTool.insertModule).render,
      legend(s"${messages(nameStr)}"),
      div(
        FormGroupInlineCp(names = List.empty)(
          SelectInlineNoFormGroupCp.Props(
            value = accordKind,
            label = messages("sampleEvidence"),
            name = s"${namePrefix}.accordKind",
            optionMap = accordKindMap,
            onChange = FTool.accordKindChange
          ).render,
          SelectInlineNoFormGroupCp.Props(
            value = calculateMethod,
            label = messages("calculationMethod"),
            name = s"${namePrefix}.calculateMethod",
            optionMap = calculateMethodMap,
            onChange = FTool.calculateMethodChange
          ).render
        ),
        FormGroupInlineCp(
          names = List(s"${namePrefix}.constant", s"${namePrefix}.topN", s"${namePrefix}.topPercent")
        )(
          SelectInlineNoFormGroupCp.Props(
            value = keepMethod,
            label = messages("retentionMethod"),
            name = s"${namePrefix}.keepMethod",
            optionMap = keepMethodMap,
            onChange = FTool.keepMethodChange
          ).render,
          InputInlineNoFormGroupCp.Props(
            value = constant,
            show = (keepMethod == "more"),
            label = messages("constant"),
            inputWidth = 3,
            name = s"${namePrefix}.constant",
            onChange = FTool.constantChange
          ).render,
          InputInlineNoFormGroupCp.Props(
            value = topN,
            show = (keepMethod == "top"),
            label = "TopN",
            name = s"${namePrefix}.topN",
            inputWidth = 3,
            onChange = FTool.topNChange
          ).render,
          InputInlineNoFormGroupCp.Props(
            label = messages("percentage"),
            questionInfo = messages("percentInfo"),
            value = topPercent,
            onChange = FTool.topPercentChange,
            name = s"${namePrefix}.topPercent",
            show = (keepMethod == "topPercent"),
            inputWidth = 3
          ).render
        )
      )
    )

  }

  def cp(
      curI: Int,
      datas: List[EachPreprocessData],
      datasChange: List[EachPreprocessData] => SyncIO[Unit],
      insertModule: String => SyncIO[Unit],
      removeModule: Int => SyncIO[Unit],
      extraData: ExtraData
  ) = {
    LevelRemoveCp.Props(
      curI = curI,
      datas = datas,
      datasChange = datasChange,
      insertModule = insertModule,
      removeModule = removeModule
    ).render
  }

}
